package com.chats.interceptor;

import com.alibaba.fastjson.JSONObject;

import com.chats.common.Result;
import com.chats.util.JwtUtils;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Component
@Slf4j
public class jwtTokenUserInterceptor implements HandlerInterceptor {

    @Override //目标资源方法运行前运行，true放行，false不放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {


        //1.获取请求的URL
        String url = request.getRequestURL().toString();
        //3.获取请求中的令牌token
        String jwt = request.getHeader("Authorization");
        log.info("请求的头：{}",jwt);
        if (jwt != null && jwt.startsWith("Bearer ")) {
            jwt = jwt.substring("Bearer ".length()); // 去除"Bearer "前缀
        }

            //4.判断是否存在，若不存在，返回错误结果
        if(!StringUtils.hasLength(jwt)){
            log.info("令牌不存在");
            Result error = Result.error("NOT_LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);

            return false;
        }
        //5.解析token，如果解析失败，返回错误结果（未登录）
        try {
            log.info("用户token：{}", jwt);
            JwtUtils.parseJWT(jwt);
            return true;
        } catch (ExpiredJwtException e) {  // 处理过期异常
            log.error("令牌已过期", e);
            handleJwtException(e, response);
            return false;
        } catch (SignatureException e) {  // 处理签名验证失败
            log.error("令牌签名验证失败", e);
            handleJwtException(e, response);
            return false;
        } catch (Exception e) {  // 其他异常
            log.error("令牌解析失败", e);
            handleJwtException(e, response);
            return false;
        }
    }

    @Override //目标资源方法运行后运行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //System.out.println("postHandle...");
    }

    @Override //视图渲染完毕后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //System.out.println("afterCompletion...");
    }
    private void handleJwtException(Exception e, HttpServletResponse response) {
        log.info("令牌失效");
        e.printStackTrace();
        Result error = Result.error("NOT_LOGIN");
        String notLogin = JSONObject.toJSONString(error);
        try (PrintWriter writer = response.getWriter()) {
            writer.write(notLogin);
        } catch (IOException ex) {
            log.error("响应未登录结果失败", ex);
        }
    }
}
